package net.njcp.icodes.util;

/**
 * @ClassName ConvertUtil
 * @Description: TODO
 * @Author 柳拓
 * @Date 2019/8/19
 * @Version V1.0
 **/
public class ConvertUtil {

    /**
     *
     * @param b 字节数组
     * @return
     */
    public static String bytes2hexstr(byte[] b) {
        return bytes2hexstr(b, false, "");
    }

    /**
     *
     * @param b 字节数组
     * @param seprator 分隔符
     * @return
     */
    public static String bytes2hexstr(byte[] b, String seprator) {
        return bytes2hexstr(b, false, seprator);
    }

    public static String bytes2hexstr(byte[] b, boolean highBitFirst){
        return bytes2hexstr(b, highBitFirst, "");
    }

    /**
     *
     * @param b 字节数组
     * @param highBitFirst true:高位优先，即输出的十六进制字符串是从Byte数组的最大下标开始的 小端
     *                     false:低们优先，即输出的十六进制字符串是从Byte数组的最小下标0开始的 大端
     * @param seprator 分隔符
     * @return
     */
    public static String bytes2hexstr(byte[] b, boolean highBitFirst, String seprator) {
        String result = null;

        if (b != null && b.length > 0) {
            if (highBitFirst) {
                for (int i = b.length - 1; i >= 0; i--) {
                    String hex = byte2hex(b[i]);
                    if (result == null)
                        result = hex;
                    else
                        result += seprator + hex;
                }
                result = result.toUpperCase();
            } else {
                for (int i = 0; i < b.length; i++) {
                    String hex = byte2hex(b[i]);
                    if (result == null)
                        result = hex;
                    else
                        result += seprator + hex;
                }
                result = result.toUpperCase();
            }
        }
        return result;
    }

    /**
     * 把字节转换成十六进制字符串，固定为两个字符长度
     *
     * @param b 字节
     * @return
     */
    public static String byte2hex(byte b) {
        String result = null;

        result = Integer.toHexString((b >> 4) & 0x0f);
        result += Integer.toHexString(b & 0xf);
        return result.toUpperCase();
    }

    public static byte getBits(byte b,int start,int length) {
        int value1 = b>>start;
        //根据length获取固定长度00011111
        int value2 = 0xFF>>(8-length);
        //只有11111部分才会在&的过程保留下来
        int value3 = value1&value2;
        byte bit = (byte)value3;
        //(byte) ((b>>start)&(0xFF>>(8-length)));
        return bit;
    }

    public static byte setBits(byte value, byte b,int start) {
        int value1 = value<<start;
        int value2 = value1|b;
        byte bit = (byte)value2;
        return bit;
    }

    public static byte[] setBits(byte[] value, byte b,int start) {
        String hex = ConvertUtil.bytes2hexstr(value);
        long value1 = Long.parseLong(hex,16)<<start;
        long value2 = value1|b;
        if(value.length==1){
            return new byte[]{(byte)value2};
        }else if(value.length==2){
            return ConvertUtil.short2bytes((int) value2);
        }else if(value.length==4){
            return ConvertUtil.int2bytes((int) value2);
        }
        return null;
    }

    public static String getBitString(byte b,int start,int length){
        int value = getBits(b, 0, 5);
        return Integer.toBinaryString(value);
    }

    public static short bytes2short(byte[] b) {
        return (short) bytes2long(b);
    }

    public static int bytes2int(byte[] b) {
        return (int) bytes2long(b);
    }

    /**
     * 字节数组转成长整形。按高位在前进行转换。
     *
     * @param b
     * @return
     */
    public static long bytes2long(byte[] b) {
        return bytes2long(b, true);
    }

    /**
     * 字节数组转成长整形
     *
     * @param b
     * @param isHighFirst
     *            是否高位在前
     * @return
     */
    public static long bytes2long(byte[] b, boolean isHighFirst) {
        long result = 0;

        if (b != null && b.length <= 8) {
            long value;

            if (isHighFirst) {
                for (int i = b.length - 1, j = 0; i >= 0; i--, j++) {
                    value = (long) (b[i] & 0xFF);
                    result += value << (j << 3);
                }
            } else {
                for (int i = 0, j = 0; i < b.length; i++, j++) {
                    value = (long) (b[i] & 0xFF);
                    result += value << (j << 3);
                }
            }
        }

        return result;
    }

    /**
     * 把十六进制字符串转化成字节数组 如果长度不是偶数的话，前面加“0”
     *
     * @param hexstr
     * @return
     */
    public static byte[] hexstr2bytes(String hexstr) {
        byte[] b = null;
        int len = 0;

        if (hexstr != null) {

            if (hexstr.length() % 2 != 0)
                hexstr = "0" + hexstr;
            len = hexstr.length() / 2;
            b = new byte[len];

            String temp = hexstr + "0";
            for (int i = 0, j = 0; i < temp.length() - 2; i += 2, j++) {
                b[j] = hex2byte(temp.substring(i, i + 2));

            }
        }
        return b;
    }

    /**
     * 把十六进制数转化成字节
     *
     * @param hex
     * @return
     */
    public static byte hex2byte(String hex) {
        byte b = 0;
        int value = 0;

        if (hex != null && hex.length() <= 2) {
            hex = hex.toUpperCase();
            if (hex.length() == 0)
                return 0;
            else if (hex.length() >= 1) {
                value = hex.charAt(0);
                if (value < 48 || (value > 57 && value < 65) || value > 70)
                    return 0;

                if (hex.length() == 2) {
                    value = hex.charAt(1);
                    if (value < 48 || (value > 57 && value < 65) || value > 70)
                        return 0;
                }
            }

            try {
                b = (byte) Integer.parseInt(hex, 16);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        return b;
    }

    public static byte[] long2bytes(long value, boolean isHighFirst) {
        byte[] b = new byte[8];

        if (isHighFirst) {
            for (int i = 0; i < 8; i++) {
                b[i] = (byte) (value >> (8 * (7 - i)) & 0xFF);
                // System.out.println("b["+i+"]:"+ byte2hex(b[i]));
            }
        } else {
            for (int i = 0, j = 7; i < 8; i++, j--)
                b[j] = (byte) (value >> (8 * (7 - i)) & 0xFF);

        }

        return b;
    }

    public static byte[] int2bytes(int a, boolean isHighFirst) {
        byte[] result = new byte[4];

        if (isHighFirst) {
            result[0] = (byte) (a >> 24 & 0xff);
            result[1] = (byte) (a >> 16 & 0xff);
            result[2] = (byte) (a >> 8 & 0xff);
            result[3] = (byte) (a & 0xff);
        } else {
            result[3] = (byte) (a >> 24 & 0xff);
            result[2] = (byte) (a >> 16 & 0xff);
            result[1] = (byte) (a >> 8 & 0xff);
            result[0] = (byte) (a & 0xff);
        }
        return result;
    }

    public static byte[] short2bytes(int a, boolean isHighFirst) {
        byte[] result = new byte[2];

        if (isHighFirst) {

            result[0] = (byte) (a >> 8 & 0xff);
            result[1] = (byte) (a & 0xff);
        } else {

            result[1] = (byte) (a >> 8 & 0xff);
            result[0] = (byte) (a & 0xff);
        }
        return result;
    }

    public static byte[] short2bytes(int a) {
        return short2bytes(a, true);
    }

    public static byte[] int2bytes(int a) {
        return int2bytes(a, true);
    }

    public static byte[] long2bytes(long value) {
        return long2bytes(value, true);
    }

    public static String byteArrToBinStr(byte[] b) {
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            result.append(Long.toString(b[i] & 0xff, 2) + ",");
        }
        return result.toString().substring(0, result.length() - 1);
    }

    /**
     * 二进制字符串转换为byte数组,每个字节以","隔开
     **/
    public static byte[] binStrToByteArr(String binStr) {
        String[] temp = binStr.split(",");
        byte[] b = new byte[temp.length];
        for (int i = 0; i < b.length; i++) {
            b[i] = Long.valueOf(temp[i], 2).byteValue();
        }
        return b;
    }

    public static byte getCheckByte(byte[] array,int startByte, int position){
        int value = 0 ;
        for(int i = startByte ; i < position ; i ++ ){
            value += array[i];
        }
        return (byte) (value%0x100) ;
    }

    /**
     *byte[]转化成10进制字符串
     **/
    public static String bytes2dec(byte[] bytes){
        StringBuilder s= new StringBuilder();
        for (byte a : bytes) {
            String b = Integer.toHexString(a&0xFF);
            b=b.length()==1?"0"+b:b;
            s.append(b);
        }
        String value;
        try {
            Long lon = Long.valueOf(s.toString());
            value = lon.toString();
        }catch (Exception E){
            value = s.toString();
        }

        return value;
    }

    /**
     *byte转化成10进制字符串
     **/
    public static String byte2dec(byte b){
       String bs = ""+b;
       return bs.length()==1?"0"+bs:bs;
    }
}
